
#import "scan_control.h"
#import <bsd/dev/scsireg.h>
#import <sys/param.h>
#import "scanView.h"
#import "ScanDisplay.h"
#import "DisplayControl.h"

@implementation scan_control

- init
{
	[super init];
	[self findScanner];
	scanImage = 0x0;
	return self;
}

- doScan:sender
{
	int xstart = [xstartText intValue];
	int ystart = [ystartText intValue];
	int width = [widthText intValue];
	int length = [lengthText intValue];

	scanImage = (NXBitmapImageRep *)[scanner performScan:xstart :ystart
														:width :length
														preview:NO ];
	if (scanImage )
	{
	   [scanDisplay drawBitmap:scanImage :xstart :ystart];
	   [self newDisplay:self];
	}
    return self;
}

- doPreview:sender
{
	scanImage = (NXBitmapImageRep *)[scanner performPreview];
	if (scanImage )
	{
	   [scanDisplay drawBitmap:scanImage :0 :0];
	   [scanImage free];
	}
    return self;
}

- photocopy:sender
{
	int xstart = [xstartText intValue];
	int ystart = [ystartText intValue];
	int width = [widthText intValue];
	int length = [lengthText intValue];

	scanImage = (NXBitmapImageRep *)[scanner performScan:xstart :ystart
														:width :length
														preview:NO ];
	if (scanImage )
	{
	   [scanDisplay drawBitmap:scanImage :xstart :ystart];
	   [[NXApp printInfo] setMarginLeft:0 right:0 top:0 bottom:0];
	   [scanDisplay printPSCode:nil];
	   [scanImage free];
	}

	return self;
}

- findScanner
{
    struct scsi_adr sa;
    struct scsi_req sr;
    struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;

    char returnData[148];           // Read the inquiry response into here.
	char* name;
	int target;
	int scannerFD;
	
	// Can we open the generic scsi device? If not, we pop up a
	// panel and then quit.
	
    if ((scannerFD = open("/dev/sg0", O_RDWR, 0666)) <= 0)
	{
        NXRunAlertPanel("Error",
			            "Unable to open scanner device /dev/sg0",
						"OK", NULL, NULL);
        exit(-1);
    }
	
    // Start scanning through all the scsi devices. Assume (of course)
	// that the scanner will be at LUN 0.
	
    for(target = 0; target <= 7; target++)
	{
		sa.sa_target = target;
        sa.sa_lun = 0;

		// if a device is present at the target number....
		// (this ioctl binds the sg controller to the target #.
		
        if (ioctl(scannerFD, SGIOCSTL, &sa) >= 0)
		{
            bzero(&sr, sizeof(struct scsi_req));

            cdbp->c6_opcode = C6OP_INQUIRY;         // Sending inquiry command
            cdbp->c6_lun = 0;                       // Assume LUN = 0
            cdbp->c6_len = sizeof(returnData);     // Number of bytes from device

            sr.sr_dma_dir = SR_DMA_RD;              // It's a read function
            sr.sr_addr    = (char *) &returnData;	// with data ending up here.
            sr.sr_dma_max = cdbp->c6_len;           // and it's this long.
            sr.sr_ioto    = 2;						// Should respond within 2 seconds.

			// If the device responded adequately...
			
            if (ioctl(scannerFD, SGIOCREQ, &sr) >= 0)
			{
				// returning good status, check to see if it's our scanner.
                if(!sr.sr_io_status)
				{
				    if ( (returnData[0x00] & 0x1F) == DEVTYPE_SCANNER)
					{
					  close(scannerFD);
					  name = &returnData[8];
					  // [self loadScannerBundle:&returnData[8] ];
					  // [self loadScannerBundle:name ];
					  name = calloc(10, sizeof(char));
					  sprintf(name, "UMAX");
					  [self loadScannerBundle:name];
					  return self;
					}
                }
            }
        }
    }

    NXRunAlertPanel("Error","No supported scanner found!", "OK", NULL, NULL);

	[NXApp terminate:self];
    return self;
}

- loadScannerBundle:(char *)name
{
    char currentPath[MAXPATHLEN+1]; // path to current (app) directory
	char message[80];
	char *suffix;
	NXBundle *myBundle = 0;

	// suffix = index(name, ' ');				// end of scanner name
    suffix = name + 8;
	*suffix = '\0';               			// terminate after name
	strcat(name, ".bundle\0");       		// append .bundle suffix
	strcpy(currentPath, NXArgv[0]);			// get path to app
	suffix = rindex(currentPath, '/') + 1;	// find last slash (plus 1 character)
	*suffix = '\0';							// eliminate the app name
	strcat(currentPath, name);       		// append .bundle suffix
	
	myBundle = [[NXBundle alloc] initForDirectory:currentPath];   // get a bundle
	scanner = [[[ myBundle principalClass] alloc] init];		  // and load the class

	if (scanner == 0)
	{
		sprintf(message, "Couldn't locate %s!", name);
		NXRunAlertPanel("Error", message, "OK", NULL, NULL);
		[NXApp terminate:self];
	}

	if (![[scanner class] conformsTo:@protocol(Scanner)])
	{
		sprintf(message, "Found scanner, but %s\ndoes not conform to Scanner protocol!", name);
		NXRunAlertPanel("Error", message, "OK", NULL, NULL);
		[NXApp terminate:self];
	}
		
	[myBundle free];
	return self;
}

- newDisplay:sender
{
	id win;
	if ([NXApp loadNibSection: "scanDisplay.nib" owner:self] == nil)
	{
		return nil;
    }
	
	if ([newDisplay setUp:scanImage])
	{
		win = [newDisplay window];
		if (win)
		{
			NXRect frame;
			char buf[256];
			
			[win getFrame: &frame];
			NX_X(&frame) += offset;
			NX_Y(&frame) -= offset;
			if ( (offset += 25.0) > 100.0) offset = 0.0;
			
			sprintf(buf, [win title], ++scanNum);
			[win setTitle: buf];
			[win placeWindowAndDisplay: &frame];
			[win makeKeyAndOrderFront: nil];
			return newDisplay;
		}
	}
	return nil;
}

@end
